package com.coolw.spring.statemachine.support.order;

import com.coolw.common.exception.ExceptionUtil;
import com.coolw.spring.statemachine.constant.StateMachineConst;
import com.coolw.spring.statemachine.enums.OrderEvent;
import com.coolw.spring.statemachine.enums.OrderStatusEnum;
import com.coolw.spring.statemachine.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * 订单状态变化监听器
 *
 * @author coolw
 * @date 2024/4/13 22:13
 */
@Slf4j
@Component
@WithStateMachine(id = OrderStateMachineBuilder.MACHINE_ID)
public class OrderStateMachineListener {

    @Resource
    private OrderService orderService;

    @OnTransition(source = "WAIT_PAYMENT", target = "WAIT_DELIVER")
    public void pay(Message<OrderEvent> message) {
        log.info("用户完成支付,待发货! 状态机反馈信息:{}", message.getHeaders());
        updateOrderStatus(message, OrderStatusEnum.WAIT_DELIVER);
    }

    @OnTransition(source = "WAIT_DELIVER", target = "WAIT_RECEIVE")
    public void deliver(Message<OrderEvent> message) {
        log.info("订单已发货,待收货! 状态机反馈信息:{}", message.getHeaders());
        updateOrderStatus(message, OrderStatusEnum.WAIT_RECEIVE);
    }

    @OnTransition(source = "WAIT_RECEIVE", target = "FINISH")
    public void receive(Message<OrderEvent> message) {
        log.info("用户已收货,订单完成! 状态机反馈信息:{}", message.getHeaders());
        updateOrderStatus(message, OrderStatusEnum.FINISH);
    }

    private void updateOrderStatus(Message<OrderEvent> message, OrderStatusEnum targetStatus) {
        MessageHeaders headers = message.getHeaders();

        OrderContext orderContext = (OrderContext) headers.get(StateMachineConst.CONTEXT_KEY);
        if (Objects.isNull(orderContext)) {
            throw ExceptionUtil.createBusinessException("订单信息为空");
        }

        // 更新订单状态
        orderService.updateOrderStatus(orderContext.getOrderId(), targetStatus);
    }
}
